package com.runvp.service.biz.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.runvp.common.core.text.Convert;
import com.runvp.common.enums.CargoUseStatus;
import com.runvp.common.enums.EnableStatus;
import com.runvp.common.enums.OrderPayStatus;
import com.runvp.common.enums.OrderStatus;
import com.runvp.common.exception.base.BaseException;
import com.runvp.common.util.ToolUtils;
import com.runvp.common.utils.DateUtils;
import com.runvp.service.biz.domain.BizDeviceCargo;
import com.runvp.service.biz.domain.BizOrder;
import com.runvp.service.biz.domain.BizOrderItem;
import com.runvp.service.biz.handler.CmdCommonHandler;
import com.runvp.service.biz.mapper.BizDeviceCargoMapper;
import com.runvp.service.biz.mapper.BizOrderItemMapper;
import com.runvp.service.biz.mapper.BizOrderMapper;
import com.runvp.service.biz.service.IBizDeviceCargoService;
import com.runvp.service.biz.service.IBizOrderService;
import com.runvp.service.out.OutUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 订单Service业务层处理
 * 
 * @author runvp
 * @date 2022-12-27
 */
@Slf4j
@Service
public class BizOrderServiceImpl implements IBizOrderService {
    @Autowired
    private CmdCommonHandler cmdCommonHandler;
    @Autowired
    private BizOrderMapper bizOrderMapper;
    @Autowired
    private BizDeviceCargoMapper bizDeviceCargoMapper;
    @Autowired
    private BizOrderItemMapper bizOrderItemMapper;

    @Autowired
    private IBizDeviceCargoService bizDeviceCargoService;
    /**
     * 定时检测是否有超时订单,如果有则关闭
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void taskCheckOrder(Integer minutes){
        if(null == minutes){
            minutes = 1;
        }
        BizOrder query = new BizOrder();
        query.setStatus(OrderStatus.GO_ON.getCode());
        query.setEnable(EnableStatus.ENABLE.getCode());
        List<BizOrder> orders = selectBizOrderList(query);
        if(CollectionUtils.isEmpty(orders)){
            log.warn("暂无超时订单");
            return;
        }
        for(BizOrder order:orders){
            try{
                //计算是否超时
                if(ToolUtils.calcTimeout(order.getCreateTime(),minutes)){
                    //超时处理
                    log.info("本次处理超时订单【{}】",order.getOrderNo());
                    order.setSuccessTime(new Date());
                    order.setPayStatus(OrderPayStatus.TIMEOUT_CLOSE.getCode());
                    order.setStatus(OrderStatus.TIMEOUT_CLOSE.getCode());
                    order.setUpdateBy("系统自动关闭");
                    order.setRemark("超时系统自动关闭");
                    updateBizOrder(order);
                    //释放库存
//                    releaseGoodsStock(order.getOrderNo());
                }
            }catch (Exception e){
                log.error("本次处理超时订单【{}】异常:{}",order.getOrderNo(),e);
            }
        }
    }

    /**
     * 释放库存
     */
    @Transactional(rollbackFor = Exception.class)
    public void releaseGoodsStock(String orderNo){
        BizOrderItem query = new BizOrderItem();
        query.setOrderNo(orderNo);
        List<BizOrderItem> itemList = bizOrderItemMapper.selectBizOrderItemList(query);
        if(CollectionUtils.isEmpty(itemList)){
            log.warn("订单【{}】没有需要释放的库存",orderNo);
            return;
        }
        BizDeviceCargo cargo;
        int number;
        for(BizOrderItem item:itemList){
            number = ToolUtils.toInt(item.getDevicePort());
            cargo = bizDeviceCargoMapper.selectBizDeviceCargoBySnAndNumber(new BizDeviceCargo(item.getDeviceSn(),number));
            if(null == cargo){
                log.warn("设备【{}】端口【{}】不存在,跳过",item.getDeviceSn(),number);
                continue;
            }
            String msg = String.format("时间【"+DateUtils.getTime()+"】已释放库存【%s】件",item.getGoodsNum());
            item.setRemark(item.getRemark()+"\n"+msg);
            bizOrderItemMapper.updateBizOrderItem(item);
            //加回库存
            cargo.setGoodsStock(ToolUtils.toInt(cargo.getGoodsStock())+ToolUtils.toInt(item.getGoodsNum()));
            cargo.setUpdateBy("系统处理");
            cargo.setUpdateTime(new Date());
            cargo.setRemark("订单超时,本次释放库存:"+ToolUtils.toInt(item.getGoodsNum()));
            bizDeviceCargoMapper.updateBizDeviceCargo(cargo);
        }
    }


    /**
     * 查询订单
     * 
     * @param id 订单主键
     * @return 订单
     */
    @Override
    public BizOrder selectBizOrderById(Long id) {
        return bizOrderMapper.selectBizOrderById(id);
    }
    /**
     * 查询订单信息
     * @param orderNo
     * @return BizOrder
     */
    public BizOrder selectBizOrderByOrderNo(String orderNo){
        return bizOrderMapper.selectBizOrderByOrderNo(orderNo);
    }
    /**
     * 查询订单列表
     * 
     * @param bizOrder 订单
     * @return 订单
     */
    @Override
    public List<BizOrder> selectBizOrderList(BizOrder bizOrder) {
        return bizOrderMapper.selectBizOrderList(bizOrder);
    }

    /**
     * 新增订单
     * 
     * @param bizOrder 订单
     * @return 结果
     */
    @Override
    public int insertBizOrder(BizOrder bizOrder) {
        bizOrder.setCreateTime(DateUtils.getNowDate());
        return bizOrderMapper.insertBizOrder(bizOrder);
    }

    /**
     * 修改订单
     * 
     * @param bizOrder 订单
     * @return 结果
     */
    @Override
    public int updateBizOrder(BizOrder bizOrder) {
        bizOrder.setUpdateTime(DateUtils.getNowDate());
        return bizOrderMapper.updateBizOrder(bizOrder);
    }

    /**
     * 关闭订单
     * @param id 订单
     * @return 结果
     */
    @Override
    public int close(Long id){
        BizOrder order = selectBizOrderById(id);
        if(null == order){
            throw new BaseException("订单不存在或已删除");
        }
        String oid = order.getOrderNo();
        //发送停止充电指令
        JSONObject param = new JSONObject();
        param.put("po",order.getPort());
        param.put("oid", oid);
        boolean res = OutUtil.stop(order.getDeviceSn(),param.toJSONString());
        log.info("停止充电指令发送状态:【{}】",res);
        //订单退款结算
        BizOrder refund = new BizOrder();
        refund.setOrderNo(oid);
        refund.setAmount(order.getAmount());
        refund.setCustomerId(order.getCustomerId());
        refund.setType(order.getType());
        refund.setCreateBy(order.getCreateBy());
        cmdCommonHandler.buildCustomerRefundTranLog("强制关闭订单退款: ",refund);
        String over = String.format("\n时间【%s】订单强制关闭结算(本次共消费【0】元,退回账户【%s】元)", DateUtils.getTime(),order.getAmount());
        order.setRemark(order.getRemark()+over);
        order.setStatus(OrderStatus.CLOSE.getCode());
        order.setPayAmount(BigDecimal.ZERO);
        order.setPayStatus(OrderPayStatus.PAY_CLOSE.getCode());
        order.setSuccessTime(new Date());
        updateBizOrder(order);
        log.info("【{}】强制关闭订单,处理成功",oid);
        bizDeviceCargoService.usePort(order.getCargoId(), CargoUseStatus.IDLE.getCode());
        log.info("【{}】强制关闭订单,端口释放成功",oid);
        return 1;
    }
    /**
     * 批量删除订单
     * 
     * @param ids 需要删除的订单主键
     * @return 结果
     */
    @Override
    public int deleteBizOrderByIds(String ids) {
        return bizOrderMapper.deleteBizOrderByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除订单信息
     * 
     * @param id 订单主键
     * @return 结果
     */
    @Override
    public int deleteBizOrderById(Long id) {
        return bizOrderMapper.deleteBizOrderById(id);
    }
}
